排序算法c语言描述---基数排序

排序算法系列学习,主要描述冒泡排序,选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序等排序进行分析。

文章规划:

一。通过自己对排序算法本身的理解,对每个方法写个小测试程序。 具体思路分析不展开描述。

二。通过《大话数据结构》一书的截图,详细分析该算法 。 

在此,推荐下程杰老师的《大话数据结构》一书,当然不是打广告,只是以一名读者的身份来客观的看待这本书,确实是通俗易懂,值得一看。

ps:一个较为详细的学习链接   http://blog.csdn.net/MoreWindows/article/category/859207


九。基数排序

一。个人理解

必须说明下,在《大话数据结构》一书中并没有基数排序这算法,而我对该算法的学习也是来自网上一些教程。

所以可能描述的不够详细,还望见谅。


首先,不得不说,基数排序这算法的排序过程算是比较好玩的,比较特别,为那些大胡子致敬。

编程论到极致,核心非代码,即思想。  一点不假


基数排序(以整形为例),将整形10进制按每位拆分,然后从低位到高位依次比较各个位。每次比较完进行排序,直到整个数组有序
主要分为两个过程:
(1)分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中(比如53,个位为3,则放入3号桶中)
(2)收集,再将放置在0~9号桶中的数据按顺序放到数组中
重复(1)(2)过程,从个位到最高位,直到排好序为止(比如32位无符号整形最大数4294967296,最高位10位)


下面举例说明:

(1)假设有欲排数据序列如下所示:

73  22  93  43  55  14  28  65  39  81

首先根据个位数的数值,在遍历数据时将它们各自分配到编号0至9的桶(个位数值与桶号一一对应)中。

分配结果(逻辑想象)如下图所示:


分配结束后。接下来将所有桶中所盛数据按照桶号由小到大(桶中由顶至底)依次重新收集串起来,得到如下仍然无序的数据序列:

81  22  73  93  43  14  55  65  28  39

接着,再进行一次分配,这次根据十位数值来分配(原理同上),分配结果(逻辑想象)如下图所示:


分配结束后。接下来再将所有桶中所盛的数据(原理同上)依次重新收集串接起来,得到如下的数据序列:

14  22  28  39  43  55  65  73  81  93

观察可以看到,此时原无序数据序列已经排序完毕。如果排序的数据序列有三位数以上的数据,则重复进行以上的动作直至最高位数为止。



现在如果还不理解的话,再看下面一个例子:


以【521 310 72 373 15 546 385 856 187 147】序列为例,具体细节如下图所示:


在数据中最高位为3,进行了三次分配、收集过程后,变成有序数组。


讲到这里,想必大家对基数排序的思想已经了解了。下面具体看代码。

#include<stdio.h>

#define Max_ 10      //数组个数
#define RADIX_10 10    //整形排序
#define KEYNUM_31 10     //关键字个数,这里为整形位数

// 打印结果
void Show(int  arr[], int n)
{
    int i;
    for ( i=0; i<n; i++ )
        printf("%d  ", arr[i]);
    printf("\n");
}

// 找到num的从低到高的第pos位的数据
int GetNumInPos(int num,int pos)
{
	int temp = 1;
	for (int i = 0; i < pos - 1; i++)
		temp *= 10;
    
	return (num / temp) % 10;
}


//基数排序  pDataArray 无序数组;iDataNum为无序数据个数
void RadixSort(int* pDataArray, int iDataNum)
{
	int *radixArrays[RADIX_10];    //分别为0~9的序列空间
	for (int i = 0; i < 10; i++)
	{
		radixArrays[i] = (int *)malloc(sizeof(int) * (iDataNum + 1));
		radixArrays[i][0] = 0;    //index为0处记录这组数据的个数
	}
	
	for (int pos = 1; pos <= KEYNUM_31; pos++)    //从个位开始到31位
	{
		for (int i = 0; i < iDataNum; i++)    //分配过程
		{
			int num = GetNumInPos(pDataArray[i], pos);
			int index = ++radixArrays[num][0];
			radixArrays[num][index] = pDataArray[i];
		}
        
		for (int i = 0, j =0; i < RADIX_10; i++)    //收集
		{
			for (int k = 1; k <= radixArrays[i][0]; k++)
				pDataArray[j++] = radixArrays[i][k];
			radixArrays[i][0] = 0;    //复位
		}
	}
}

int main()
{   //测试数据
    int arr_test[Max_] = { 8, 4, 2, 3, 5, 1, 6, 9, 0, 7 };
    //排序前数组序列
    Show( arr_test, Max_ );
    RadixSort( arr_test, Max_);
    //排序后数组序列
    Show( arr_test, Max_ );
    return 0;
}


注:这个算法也是今天才学的。   一些见解和例子来自一些大牛的博客,具体参见下面我给的链接。


这里,因为《大话数据》结构一书中没有介绍基数排序这个算法,如果我描述的不够详细,具体可以看下面我给出的这些链接,都是不错的学习资料。


太阳落雨  csdn博客 :http://blog.csdn.net/cjf_iceking/article/details/7943609

云卷云舒 博客园:       http://www.cnblogs.com/Braveliu/archive/2013/01/21/2870201.html

算法与数据结构    http://iprai.hust.edu.cn/icl2002/algorithm/algorithm/commonalg/sort/internal_sorting/radix_sort/radix_sort.htm

维基百科           http://zh.wikipedia.org/wiki/基数排序

平凡的程序员  csdn博客 :  http://blog.csdn.net/feixiaoxing/article/details/6876831



自己先标注下,便于以后复习。




  • 43
    点赞
  • 108
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
基数排序算法是一种稳定排序算法,适用于数值比较大的数据之间的排序。它不涉及元素之间的比较,而是根据基数将数据存放到相应的“桶”里,经过多趟排序过程,最终实现对一组散乱数据的排序。 基数排序的实现思路如下: 1. 首先确定待排序数组中最大值的位数,记为max_digits。 2. 创建10个桶,对每个桶进行计数初始化。 3. 从低位到高位,依次对待排序数组中的元素进行入桶操作。 4. 将桶中的元素按顺序依次取出,得到新的排序结果。 5. 重复第3和第4步,直到所有元素中的最高位已经处理完毕。 6. 最终得到的排序结果就是基数排序的结果。 下面是基数排序C语言实现示例: ```c #include <stdio.h> // 获取数组中最大值的位数 int getMaxDigits(int arr[], int n) { int max = arr[0]; for (int i = 1; i < n; i++) { if (arr[i] > max) { max = arr[i]; } } int digits = 0; while (max > 0) { max /= 10; digits++; } return digits; } // 对数组进行基数排序 void radixSort(int arr[], int n) { int max_digits = getMaxDigits(arr, n); int count[10]; int bucket[n]; int divisor = 1; for (int i = 0; i < max_digits; i++) { // 初始化计数数组和桶 for (int j = 0; j < 10; j++) { count[j] = 0; } // 统计每个桶中的元素个数 for (int j = 0; j < n; j++) { int digit = (arr[j] / divisor) % 10; count[digit]++; } // 计算每个桶中元素的起始位置 for (int j = 1; j < 10; j++) { count[j] += count[j - 1]; } // 将元素按照当前位的值放入对应的桶中 for (int j = n - 1; j >= 0; j--) { int digit = (arr[j] / divisor) % 10; bucket[count[digit] - 1] = arr[j]; count[digit]--; } // 将桶中的元素按顺序放回原数组 for (int j = 0; j < n; j++) { arr[j] = bucket[j]; } divisor *= 10; } } int main() { int arr[] = {53, 89, 150, 36, 633, 233, 197, 9, 473, 27}; int n = sizeof(arr) / sizeof(arr[0]); printf("原数组:"); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } radixSort(arr, n); printf("\n排序后的数组:"); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Colin丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值